package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/robotn/gohook"
	"io"
	"net/http"

	"github.com/gorilla/websocket"
)

func main() {
	InitMyApp()
}

var ch = make(chan bool)

//export InitMyApp
func InitMyApp() {
	go StartServer()
	go keyboardListener()
	<-ch
	fmt.Println("exiting after close")
}

var keyMap = map[uint16]string{
	1: "1",
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

var con1 *websocket.Conn

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	conn1, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		fmt.Println("Error upgrading connection:", err)
		return
	}
	con1 = conn1
	defer conn1.Close()
	fmt.Println("Client connected")

	for {
		messageType, message, err := conn1.ReadMessage()
		if err != nil {
			fmt.Println("Error reading message:", err)
			break
		}

		fmt.Printf("Received: %s\n", message)
		err = conn1.WriteMessage(messageType, message)
		if err != nil {
			fmt.Println("Error writing message:", err)
			break
		}
	}
}

func StartServer() {

	server := &http.Server{Addr: ":8080"}
	http.HandleFunc("/ws", handleWebSocket)
	http.HandleFunc("/close", func(w http.ResponseWriter, r *http.Request) {
		hook.End()
		// 等待 HTTP 服务停止
		err := server.Shutdown(context.Background())
		if err != nil {
			fmt.Printf("HTTP server shutdown error: %s\n", err)
			return
		}
		ch <- true
	})
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		b, _ := io.ReadAll(r.Body)
		fmt.Println(string(b))
		w.Header().Set("Content-Type", "text/json")
		_, _ = w.Write([]byte("ok"))
	})
	_ = http.ListenAndServe(":8080", nil)
}

func keyboardListener() {
	evChan := hook.Start()

	for ev := range evChan {
		if ev.Kind == hook.MouseUp {
			fmt.Println("Mouse event received")
			fmt.Println(ev.Button)
			if con1 == nil {
				fmt.Println("no conn")
				continue
			}
			bb, _ := json.Marshal(MouseEvent{Type: "mouseup", Key: int(ev.Button)})
			err := con1.WriteMessage(websocket.TextMessage, bb)
			if err != nil {
				fmt.Println("Error writing message:", err)
				continue
			}
		}
		if ev.Kind == hook.KeyDown || ev.Kind == hook.KeyHold {
			fmt.Println("keydown")
			if con1 == nil {
				fmt.Println("no conn")
				continue
			}
			bb, _ := json.Marshal(KeyboardEvent{Type: "keydown", Data: KeyInfo{Keycode: ev.Keycode, Rawcode: ev.Rawcode, KeyChar: "test"}, State: 1})
			err := con1.WriteMessage(websocket.TextMessage, bb)
			if err != nil {
				fmt.Println("Error writing message:", err)
				continue
			}
		}
		if ev.Kind == hook.KeyUp {
			fmt.Println("keyup")
			if con1 == nil {
				fmt.Println("no conn")
				continue
			}
			bb, _ := json.Marshal(KeyboardEvent{Type: "keyup", Data: KeyInfo{Keycode: ev.Keycode, Rawcode: ev.Rawcode, KeyChar: "test"}, State: 0})
			err := con1.WriteMessage(websocket.TextMessage, bb)
			if err != nil {
				fmt.Println("Error writing message:", err)
				continue
			}
		}
	}
}

type MouseEvent struct {
	Type string `json:"type"`
	Key  int    `json:"key"`
}
type KeyboardEvent struct {
	Type  string  `json:"type"`
	Data  KeyInfo `json:"data"`
	State uint8   `json:"state"`
}

type KeyInfo struct {
	Keycode uint16 `json:"keycode"`
	Rawcode uint16 `json:"rawcode"`
	KeyChar string `json:"keychar"`
}
